home *** CD-ROM | disk | FTP | other *** search
/ PC-X 1997 October / pcx14_9710.iso / swag / delphi.swg / 0006_Currency Edit component.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-11-22  |  8.6 KB  |  307 lines

  1. unit CurrEdit;
  2.  
  3. (**************************************************************************
  4.  This is my first custom control, so please be merciful. I needed a simple
  5.  currency edit field, so below is my attempt. It has pretty good behavior
  6.  and I have posted it up to encourage others to share their code as well.
  7.  
  8.  Essentially, the CurrencyEdit field is a modified memo field. I have put
  9.  in keyboard restrictions, so the user cannot enter invalid characters.
  10.  When the user leaves the field, the number is reformatted to display
  11.  appropriately. You can left-, center-, or right-justify the field, and
  12.  you can also specify its display format - see the FormatFloat command.
  13.  
  14.  The field value is stored in a property called Value so you should read
  15.  and write to that in your program. This field is of type Extended.
  16.  
  17.  If you like this control you can feel free to use it, however, if you
  18.  modify it, I would like you to send me whatever you did to it. If you
  19.  send me your CIS ID, I will send you copies of my custom controls that
  20.  I develop in the future. Please feel free to send me anything you are
  21.  working on as well. Perhaps we can spark ideas!
  22.  
  23.  Robert Vivrette, Owner
  24.  Prime Time Programming
  25.  PO Box 5018
  26.  Walnut Creek, CA  94596-1018
  27.  
  28.  Fax: (510) 939-3775
  29.  CIS: 76416,1373
  30.  Net: RobertV@ix.netcom.com
  31.  
  32.  Thanks to Massimo Ottavini, Thorsten Suhr, Bob Osborn, Mark Erbaugh, Ralf
  33.  
  34.  Gosch, Julian Zagorodnev, and Grant R. Boggs for their enhancements!
  35.  
  36.  Please look for this and other components in the "Unofficial Newsletter of
  37.  Delphi Users" posted on the Borland Delphi forum on Compuserve (GO DELPHI)
  38.  in the "Delphi IDE" file section.
  39.  
  40. **************************************************************************)
  41.  
  42. interface
  43.  
  44. uses
  45.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  46.   Menus, Forms, Dialogs, StdCtrls;
  47.  
  48. type
  49.   TCurrencyEdit = class(TCustomMemo)
  50.   private
  51.     DispFormat: string;
  52.     FieldValue: Extended;
  53.     FDecimalPlaces : Word;
  54.     FPosColor : TColor;
  55.     FNegColor : TColor;
  56.     procedure SetFormat(A: string);
  57.     procedure SetFieldValue(A: Extended);
  58.  
  59.     procedure SetDecimalPlaces(A: Word);
  60.     procedure SetPosColor(A: TColor);
  61.     procedure SetNegColor(A: TColor);
  62.     procedure CMEnter(var Message: TCMEnter);  message CM_ENTER;
  63.     procedure CMExit(var Message: TCMExit);    message CM_EXIT;
  64.     procedure FormatText;
  65.     procedure UnFormatText;
  66.   protected
  67.     procedure KeyPress(var Key: Char); override;
  68.     procedure CreateParams(var Params: TCreateParams); override;
  69.   public
  70.     constructor Create(AOwner: TComponent); override;
  71.   published
  72.     property Alignment default taRightJustify;
  73.     property AutoSize default True;
  74.  
  75.     property BorderStyle;
  76.     property Color;
  77.     property Ctl3D;
  78.     property DecimalPlaces: Word read FDecimalPlaces write SetDecimalPlaces default 2;
  79.     property DisplayFormat: string read DispFormat write SetFormat;
  80.     property DragCursor;
  81.     property DragMode;
  82.     property Enabled;
  83.     property Font;
  84.     property HideSelection;
  85.     property MaxLength;
  86.     property NegColor: TColor read FNegColor write SetNegColor default clRed;
  87.     property ParentColor;
  88.     property ParentCtl3D;
  89.  
  90.     property ParentFont;
  91.     property ParentShowHint;
  92.     property PopupMenu;
  93.     property PosColor: TColor read FPosColor write SetPosColor default clBlack;
  94.     property ReadOnly;
  95.     property ShowHint;
  96.     property TabOrder;
  97.     property Value: Extended read FieldValue write SetFieldValue;
  98.     property Visible;
  99.     property OnChange;
  100.     property OnClick;
  101.     property OnDblClick;
  102.     property OnDragDrop;
  103.     property OnDragOver;
  104.     property OnEndDrag;
  105.     property OnEnter;
  106.     property OnExit;
  107.     property OnKeyDown;
  108.  
  109.     property OnKeyPress;
  110.     property OnKeyUp;
  111.     property OnMouseDown;
  112.     property OnMouseMove;
  113.     property OnMouseUp;
  114.   end;
  115.  
  116. procedure Register;
  117.  
  118. implementation
  119.  
  120. procedure Register;
  121. begin
  122.   RegisterComponents('Additional', [TCurrencyEdit]);
  123. end;
  124.  
  125. constructor TCurrencyEdit.Create(AOwner: TComponent);
  126. begin
  127.   inherited Create(AOwner);
  128.   AutoSize := False;
  129.   Alignment := taRightJustify;
  130.   Width := 121;
  131.   Height := 25;
  132.   DispFormat := '$,0.00;($,0.00)';
  133.   FieldValue := 0.0;
  134.   FDecimalPlaces := 2;
  135.   FPosColor := Font.Color;
  136.   FNegColor := clRed;
  137.   AutoSelect := False;
  138.  
  139.   {WantReturns := False;}
  140.   WordWrap := False;
  141.   FormatText;
  142. end;
  143.  
  144. procedure TCurrencyEdit.SetFormat(A: String);
  145. begin
  146.   if DispFormat <> A then
  147.     begin
  148.       DispFormat:= A;
  149.       FormatText;
  150.     end;
  151. end;
  152.  
  153. procedure TCurrencyEdit.SetFieldValue(A: Extended);
  154. begin
  155.   if FieldValue <> A then
  156.     begin
  157.       FieldValue := A;
  158.       FormatText;
  159.     end;
  160. end;
  161.  
  162. procedure TCurrencyEdit.SetDecimalPlaces(A: Word);
  163. begin
  164.   if DecimalPlaces <> A then
  165.  
  166.     begin
  167.       DecimalPlaces := A;
  168.       FormatText;
  169.     end;
  170. end;
  171.  
  172. procedure TCurrencyEdit.SetPosColor(A: TColor);
  173. begin
  174.   if FPosColor <> A then
  175.     begin
  176.       FPosColor := A;
  177.       FormatText;
  178.     end;
  179. end;
  180.  
  181. procedure TCurrencyEdit.SetNegColor(A: TColor);
  182. begin
  183.   if FNegColor <> A then
  184.     begin
  185.       FNegColor := A;
  186.       FormatText;
  187.     end;
  188. end;
  189.  
  190. procedure TCurrencyEdit.UnFormatText;
  191. var
  192.   TmpText : String;
  193.   Tmp     : Byte;
  194.  
  195.   IsNeg   : Boolean;
  196. begin
  197.   IsNeg := (Pos('-',Text) > 0) or (Pos('(',Text) > 0);
  198.   TmpText := '';
  199.   For Tmp := 1 to Length(Text) do
  200.     if Text[Tmp] in ['0'..'9',DecimalSeparator] then
  201.       TmpText := TmpText + Text[Tmp];
  202.   try
  203.     If TmpText='' Then TmpText := '0.00';
  204.     FieldValue := StrToFloat(TmpText);
  205.     if IsNeg then FieldValue := -FieldValue;
  206.   except
  207.     MessageBeep(mb_IconAsterisk);
  208.   end;
  209. end;
  210.  
  211. procedure TCurrencyEdit.FormatText;
  212.  
  213. begin
  214.   Text := FormatFloat(DispFormat,FieldValue);
  215.   if FieldValue < 0 then
  216.     Font.Color := NegColor
  217.   else
  218.     Font.Color := PosColor;
  219. end;
  220.  
  221. procedure TCurrencyEdit.CMEnter(var Message: TCMEnter);
  222. begin
  223.   SelectAll;
  224.   inherited;
  225. end;
  226.  
  227. procedure TCurrencyEdit.CMExit(var Message: TCMExit);
  228. begin
  229.   UnformatText;
  230.   FormatText;
  231.   Inherited;
  232. end;
  233.  
  234. procedure TCurrencyEdit.KeyPress(var Key: Char);
  235. Var
  236.   S : String;
  237.   frmParent : TForm;
  238.   btnDefault : TButton;
  239.   i : integer;
  240.  
  241.   wID : Word;
  242.   LParam : LongRec;
  243. begin
  244.   {#8 is for Del and Backspace keys.}
  245.   if Not (Key in ['0'..'9','.','-', #8, #13]) Then Key := #0;
  246.   case Key of
  247.     #13 : begin
  248.             frmParent := GetParentForm(Self);
  249.             UnformatText;
  250.             {find default button on the parent form if any}
  251.             btnDefault := nil;
  252.             for i := 0 to frmParent.ControlCount -1 do
  253.               if frmParent.Controls[i] is TButton then
  254.                 if (frmParent.Controls[i] as TButton).Default then
  255.  
  256.                   btnDefault := (frmParent.Controls[i] as TButton);
  257.             {if there's a default button, then make the parent form think it was pressed}
  258.             if btnDefault <> nil then
  259.               begin
  260.                 wID := GetWindowWord(btnDefault.Handle, GWW_ID);
  261.                 LParam.Lo := btnDefault.Handle;
  262.                 LParam.Hi := BN_CLICKED;
  263.                 SendMessage(frmParent.Handle, WM_COMMAND, wID, longint(LParam) );
  264.               end;
  265.             Key := #0;
  266.           end;
  267.           { allow only one dot in the number }
  268.  
  269.     '.' : if ( Pos('.',Text) >0 ) then Key := #0;
  270.           { allow only one '-' in the number and only in the first position: }
  271.     '-' : if ( Pos('-',Text) >0 ) or ( SelStart > 0 ) then Key := #0;
  272.   else
  273.     { make sure no other character appears before the '-' }
  274.     if ( Pos('-',Text) >0 ) and ( SelStart = 0 ) and (SelLength=0) then Key := #0;
  275.   end;
  276.  
  277.   if Key <> Char(vk_Back) then
  278.     begin
  279.      {S is a model of Text if we accept the keystroke.  Use SelStart and
  280.  
  281.      SelLength to find the cursor (insert) position.}
  282.       S := Copy(Text,1,SelStart)+Key+Copy(Text,SelStart+SelLength+1,Length(Text));
  283.       if ((Pos(DecimalSeparator, S) > 0) and
  284.          (Length(S) - Pos(DecimalSeparator, S) > FDecimalPlaces))  {too many decimal places}
  285.            or ((Key = '-') and (Pos('-', Text) <> 0))     {only one minus...}
  286.            or (Pos('-', S) > 1)                           {... and only at beginning}
  287.       then Key := #0;
  288.  
  289.     end;
  290.  
  291.   if Key <> #0 then inherited KeyPress(Key);
  292. end;
  293.  
  294. procedure TCurrencyEdit.CreateParams(var Params: TCreateParams);
  295. var
  296.  lStyle : longint;
  297. begin
  298.   inherited CreateParams(Params);
  299.   case Alignment of
  300.     taLeftJustify  : lStyle := ES_LEFT;
  301.     taRightJustify : lStyle := ES_RIGHT;
  302.     taCenter       : lStyle := ES_CENTER;
  303.   end;
  304.   Params.Style := Params.Style or lStyle;
  305. end;
  306.  
  307. end.